<?php

class RedmineApi
{
    //типы тасков
    const TYPE_TESTING  = 5;
    const TYPE_DEFECTED = 4;
    const TYPE_DEVELOP  = 9;

    //приоритеты задачи
    const PRIORITY_NEED_THINK  = 10;
    const PRIORITY_DEVELOPMENT = 3;
    const PRIORITY_NORMAL      = 4;
    const PRIORITY_HIGHT       = 5;
    const PRIORITY_URGENT      = 6;

    //родительские проекты
    const PROJECT_TESTS          = 21;
    const PROJECT_PETS           = 31;
    const PROJECT_BILLING        = 65;
    const PROJECT_MEETING        = 44;
    const PROJECT_SUPPORT        = 72;
    const PROJECT_VOTE           = 32;
    const PROJECT_MOBILE_VERSION = 24;
    const PROJECT_SOCIAL         = 29;
    const PROJECT_FS_2_0         = 92;
    const QA                     = 91;
    const PROJECT_OTHER          = 0;

    const DOMEN    = 'http://pm.vs58.net/';
    private $login = 'stats';
    private $pass  = 'Pass@word1';
    public static $cacheProjects = array();

    private static $linksProjects = array(
        self::PROJECT_PETS => array(30, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 47, 68),
        self::PROJECT_TESTS => array(),
        self::PROJECT_BILLING => array(),
        self::PROJECT_MEETING => array(23, 59, 60, 61, 89),
        self::PROJECT_SUPPORT => array(),
        self::PROJECT_VOTE => array(),
        self::PROJECT_MOBILE_VERSION => array(),
        self::PROJECT_SOCIAL => array(),
        self::PROJECT_FS_2_0 => array(),
        self::PROJECT_OTHER => array(),
        self::QA => array(),
    );

    /**
     * @param string      $url
     * @param string      $method
     * @param array       $data
     * @param string|bool $typeData - если передать параметр false, то в curl запросе отправится $data = array()
     *
     * @return mixed
     */
    public function curlRequest($url, $method = 'GET', $data = array(), $typeData = 'issue')
    {
        $start = microtime(true);
        var_dump('step curl start');
        $authorization = base64_encode($this->login . ':' . $this->pass);

        if ($typeData !== false) {
           $data = json_encode(array(
                $typeData => $data,
            ));
        }

        $options = array(
            CURLOPT_URL            => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER     => array(
                'Accept: application/json',
                'Content-Type: application/json',
                'Authorization: Basic ' . $authorization
            ),
        );

        switch ($method) {
            case 'GET':
                if (!empty($data)) {
                    $options[CURLOPT_POSTFIELDS] = $data;
                }
                break;

            case 'POST':
                $options[CURLOPT_POST]       = true;
                $options[CURLOPT_POSTFIELDS] = $data;
                break;

            case 'PUT':
                $options[CURLOPT_CUSTOMREQUEST] = 'PUT';
                $options[CURLOPT_POSTFIELDS]    = $data;
                break;

            case 'DELETE':
                $options[CURLOPT_CUSTOMREQUEST] = 'DELETE';
                break;
        }

        $curl = curl_init();
        curl_setopt_array($curl, $options);
        $resp = curl_exec($curl);
        curl_close($curl);
        $result = json_decode($resp, true);
        $end = microtime(true);
        $time = $end - $start;
        var_dump('step curl end: ' . $time);
        return $result;
    }

    public function getIssueById($id)
    {
        if (!$id) {
            return false;
        }

        $url = self::DOMEN . 'issues/'. $id . '.json';
        $res = $this->curlRequest($url, 'GET', array(), false);
        return $res;
    }

    public function getParentProjectIdByProjectId($id)
    {
        foreach (self::$linksProjects as $parentProjectId => $subProjectsIds) {
            if ($parentProjectId == $id || in_array($id, $subProjectsIds)) {
                return $parentProjectId;
            }
        }

        return self::PROJECT_OTHER;
    }

    public function isProject($id)
    {
        if ($this->getParentProjectIdByProjectId($id)) {
            return true;
        }

        return false;
    }

    /**
     * @param string $name - имя таска
     * @param int    $idProject
     * @param string $description
     * @param int    $tracker
     * @return bool
     */
    public function createTask($name, $idProject, $description, $tracker)
    {

        if (!$name || !$idProject || !$description || !$tracker) {
            return false;
        }

        $data = array(
            'description' => $description,
            'tracker'     => intval($tracker),
            'project_id'  => intval($idProject),
            'subject'     => $name,
        );

        $res = $this->curlRequest(self::DOMEN . 'issues.json', 'POST', $data);
        return $res;
    }

    public function changeIssueStatus($issueId, $statusId, $notes = '')
    {
        if (!$issueId || !$statusId) {
            return false;
        }

        $url = 'issues/' . $issueId . '.json';
        $data = array('status_id' => $statusId, 'notes' => $notes);
        $this->curlRequest(self::DOMEN . $url, 'PUT', $data);
        return true;
    }

    public function closeIssue($issueId, $notes = '') {
        $issueId = intval($issueId);

        if (!$issueId) {
            return false;
        }

        $this->changeIssueStatus($issueId, 5, $notes);

        return true;
    }

    public function changeComment($issueId, $comment)
    {
        if (!((int) $issueId) || !$comment) {
            return false;
        }

        $url = 'issues/' . $issueId . '.json';
        $data = array('notes' => $comment);
        $this->curlRequest(self::DOMEN . $url, 'PUT', $data);
        return true;
    }

    public function changeProject($issueId, $proejctId)
    {
        if (!((int) $issueId) || !$proejctId) {
            return false;
        }

        $url = 'issues/' . $issueId . '.json';
        $data = array('project_id' => $proejctId);
        $this->curlRequest(self::DOMEN . $url, 'PUT', $data);
        return true;
    }

    public function getUser($id)
    {
        $url = 'users/' . $id . '.json';
        return $this->curlRequest(self::DOMEN . $url, 'GET', array(),false);
    }

    public function getUserIssues($userId)
    {
        if (!$userId) {
            return false;
        }

        $url = 'issues.json?assigned_to_id=' . $userId;
        $issues =  $this->curlRequest(self::DOMEN . $url, 'GET', array(), false);
        return $issues;

    }

    public function assignTo($issueId, $userId, $userName, $notes = '')
    {
        if (!$userId || !$issueId || !$userName) {
            return false;
        }

        $url = 'issues/' . $issueId . '.json';
        $data = array('assigned_to_id' => $userId, 'notes' => $notes);
        $this->curlRequest(self::DOMEN . $url, 'PUT', $data);
        return true;
    }

    public function getProjects()
    {
        if (!empty(self::$cacheProjects)) {
            return self::$cacheProjects;
        }

        $redmineProjects = $this->curlRequest(self::DOMEN . 'projects.json', 'GET', array(), false);
        $projects = array();

        foreach ($redmineProjects['projects'] as $project) {
            if ($this->isProject($project['id'])) {
                $projects['projects'][] = $project;
            }
        }

        self::$cacheProjects = $projects;
        return $projects;
    }

}